<?php

abstract class action{
	/**
	 * cast a new controller
	 * 
	 * @param string $name
	 * @return action
	 */
	public static function generate($name){
		if(!preg_match('!^[0-9a-z_]*$!i',$name)){
			throw new Exception('INVALID ACTION CHARACTERS', 404);
		}
		
		$classname = 'action_'.$name;
		
		if(!is_file(config::getDocRoot().'classes/actions/'.$classname.'.class.php')){
			throw new Exception('INVALID ACTION ['.$classname.']', 404);
		}
		
		require_once(config::getDocRoot().'classes/actions/'.$classname.'.class.php');
		
		
		if(!class_exists($classname)){
			throw new Exception('INVALID ACTION CLASS', 500);
		}
		
		$class = new $classname();
		
		if(!($class instanceof action)){
			throw new Exception('INVALID ACTION PARENT', 500);
		}
		
		return $class;
	}
	
	/**
	 * @var ADOConnection
	 */
	protected $db;
	/**
	 * @var umSmarty
	 */
	protected $smarty;
	
	protected $no_base = false;
	protected $base = 'base.tpl';
	protected $template = '';
	
	protected $cache = false;
	private $cache_id = null;
	
	private $timer = null;

	protected final function __construct(){
		if(!$this->hasAccess()){
			throw new Exception('NO ACCESS', 403);
		}
		
		$this->timer = microtime(true);
		
		$this->smarty = umSmarty::getInstance();
		$this->db = umDb::getDb();

		$this->init();
	}
	
	protected function addCacheID($string){
		$this->cache_id.= $string;
	}
	
	/**
	 * (non-PHPdoc)
	 * @see lib/smarty3/sysplugins/Smarty_Internal_Data::assign()
	 */
	protected function assign($tpl_var, $value){
		$this->smarty->assign($tpl_var, $value);
	}
	
	protected function init(){
		//just exist!
	}
	
	protected function hasAccess(){
		$user = umUser::getInstance();
		
		if($user->isLoggedIn()){
			return true;
		}else{
			return false;
		}
	}
	
	protected abstract function process($data=null);
	protected function processDynamic($data=null){
		//just exist!
	}
	
	private final function assignDefaults($cached = false){
		$this->assign('USER', umUser::getInstance());
		$this->assign('TIME_NEED', microtime(true) - $this->timer);
		$this->assign('MEMORY_NEED',memory_get_usage());
		$this->assign('CACHED',$cached);
	}
	
	public final function display($data=null){
		$cached = true;
		//check if subtemplate is in cache!
		if(!$this->cache || !empty($_POST) || ($this->cache && !$this->smarty->is_cached($this->template_base, $this->cache_id))){
			//use cache!!
			$this->process($data);
			$cached = false;
		}
		
		$this->processDynamic($data);
		$this->assignDefaults($cached);
		
		if($this->no_base){
			$this->smarty->display($this->template, ($this->cache && empty($_POST))?$this->cache_id:null);
		}else{
			$this->assign('template', $this->template);
			$this->smarty->display($this->base, ($this->cache && empty($_POST))?$this->cache_id:null);
		}
	}
}
